package pcloud.client.worker;

import java.io.IOException;

import pcloud.client.remoteservice.FileService;
import pcloud.client.util.FileResourceInfo;
import pcloud.client.util.GlobalConfig;
import pcloud.client.util.Logger;

abstract public class CloudTask
{
	protected FileResourceInfo fileInfo;

	// 这个成员保证了每个实例对象可以有自己的service,也就是说,可以通过不同的协议,连接不同的服务器;
	// 目前先按照所有任务使用同一个远程服务来初始化, 以后有需要, 放开setFileService的访问权限即可
	protected FileService fileService;

	public CloudTask(FileResourceInfo fileInfo)
	{
		this.fileInfo = fileInfo;
		this.setFileService(GlobalConfig.getRemoteFileService());
		logger.info("CloudTask created! [" + this.getClass().getSimpleName()
				+ "]" + fileInfo.toString());
	}

	private TaskMonitor taskMonitor=null;
	
	abstract protected boolean inTaskTriggerAfterDoWork();

	abstract protected boolean inTaskTriggerBeforeDoWork();

	abstract protected boolean doWork() throws IOException;
	
	public void doWorkWithTriggers()
	{
		boolean continueTo=true;

		continueTo = inTaskTriggerBeforeDoWork();
		if (!continueTo) {
			return;
		}
		if (taskMonitor !=null) {
			continueTo = taskMonitor.onBeforeDoWork(fileInfo);
		}
		if (!continueTo) {
			return;
		}
		
		try {
			continueTo = doWork();
		} catch (Exception e) {
			logger.info("handleTask error: [" + this.getFileInfo() +"] "+e.getMessage());
			return;
		}
		if (!continueTo) {
			return;
		}
		
		continueTo = inTaskTriggerAfterDoWork();
		if (!continueTo) {
			return;
		}
		if (taskMonitor !=null) {
			continueTo = taskMonitor.onAfterDoWork(fileInfo);
		}

	}

	/**
	 * 任务在执行过程中, 可能需要对正在执行的文件加锁, 以屏蔽监视器对文件变化的感知
	 * @return
	 */
	public String getBlockingFile()
	{
		return null;
	}

	public FileResourceInfo getFileInfo()
	{
		return fileInfo;
	}

	private void setFileService(FileService fileService)
	{
		this.fileService = fileService;
	}

	public void setMonitor(TaskMonitor taskMonitor)
	{
		this.taskMonitor = taskMonitor;
	}

	public TaskMonitor getMonitor()
	{
		return taskMonitor;
	}

}
